package utilities;

import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathConstants;
import javax.xml.xpath.XPathExpressionException;
import javax.xml.xpath.XPathFactory;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.w3c.dom.Document;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
/**
 * 
 * @author ahosick
 *
 */
public final class XmlUtilities {
	
	private static final Logger LOG = LoggerFactory.getLogger(XmlUtilities.class);
	/**
	 * replace || with the test name value
	 */
	private static final String FIND_BY_TEST_NAME = "//*[@testname = '||' ]";
	
	private XmlUtilities(){}

	/**
	 * Searches the document for an element with the passed test name.
	 * If there are multiple elements with the same test name, the first one will
	 * be returned
	 * @param testName
	 * @param doc - main document
	 * @return
	 */
	public static Node findNode(String testName, Document doc) {
		Node nodeInQuestion = null;
		XPath path = XPathFactory.newInstance().newXPath();
		try {
			nodeInQuestion = (Node) path.evaluate(FIND_BY_TEST_NAME.replace("||", testName), doc, XPathConstants.NODE);
		} catch (XPathExpressionException e) {
			
			LOG.error("***Node in question not found - XPathExpressionException***");
		}
		return nodeInQuestion;
	}

	/**
	 * 
	 * @param nodeToToss
	 *  @param doc - main document
	 * @param doclet - document or document containing piece to be inserted
	 *            given the params above, this will take the nodeToToss in
	 *            doc and replace it with the doclet
	 * @return will return true if change completes
	 */
	public static boolean changeNode(Node nodeToToss, Document doc,
			Document doclet) {
		boolean changeComplete = false;
		if (null!=nodeToToss) {
			//System.out.println("Node to remove was not found");
	//	}
		// will replace the node to remove with the specified file.
		//else {
			Node root = doclet.getDocumentElement();

			Node parent = nodeToToss.getParentNode();
			Node temp = doc.importNode(root, true);
			parent.replaceChild(temp, nodeToToss);
			changeComplete = true;
		}
		else{
			LOG.error("Node not changed");
		}
		return changeComplete;
	}
	/**
	 * 
	 * @param nodeToToss
	 * @param doc - main document
	 * @param nodeToInsert
	 * @param doclet - document or document containing piece to be inserted
	 *  given the params above, this will take nodeToToss in
	 *            doc and replace it with the nodeToInsert from doclet
	 * @return will return true if change completes 
	 */
	public static boolean swapNode(Node nodeToToss, Document doc, Node nodeToInsert, Document doclet){
		boolean changeComplete = false;
		if (null == nodeToToss) {
			System.out.println("Node to remove was not found");
			
		}
		else if(null == nodeToInsert){
			System.out.println("Node to insert was not found");
		}
		// will replace the node to remove with the specified file.
		else {
			
			Node parent = nodeToToss.getParentNode();
			Node temp = doc.importNode(nodeToInsert, true);
			parent.replaceChild(temp, nodeToToss);
			changeComplete = true;
		}
		return changeComplete;
	}
	
	
	/**
	 * 
	 * @param nodeToAlter
	 * @param doc
	 * @param attribute
	 * @param userInput this will take attribute in nodeToToss in
	 *            doc and replace it with the attribute from user input
	 * @return
	 */
	public static boolean changeAttribute(Node nodeToAlter, Document doc, String attribute, String userInput){
		NamedNodeMap n = nodeToAlter.getAttributes();
		Node node = n.getNamedItem(attribute);
		System.out.println("NodeName :" + node.getNodeName());
		node.setTextContent(userInput);
		
		return true;
	}
}
